 using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace GAscheduler
{
    class RulesFileReader
    {
        private Stream m_fin;                  // file stream for reading and writing files
        private string m_sRulesLines = "";     // a string containing all non-comment lines within the file being read
        private char m_cCurChar;               // current character being read from the file

        /// <summary>
        /// Constructor for the file reader. Takes a string representing the file path 
        ///     and attempts to open the file. If the file opens, it begins reading it 
        ///     until it reaches the end of the file. The relevent data is stored in the
        ///     private data member m_sRulesLines.
        /// </summary>
        /// <param name="sFilePath"></param>
        public RulesFileReader(string sFilePath)
        {
            if (!OpenFile(sFilePath))
                return;

            GetNextChar(); // position on the first char

            while (m_cCurChar != '.') // as long as we are not at the end of the file, keep reading
            {
                if (m_cCurChar == '#') // if the line is commented out
                {
                    do
                    {
                        GetNextChar(); // ignore chars until we see the beginning of a new line
                    } while (m_cCurChar != '\r'); // \r is the start of the newline phrase
                    GetNextChar();                // ignores \n
                    GetNextChar();                // positions on the first char in the next line
                }
                else  // if the line is not a comment, we want it
                {
                    do
                    {
                        m_sRulesLines += m_cCurChar.ToString(); // capture chars until the end of the line
                        GetNextChar();
                    } while (m_cCurChar != '\r'); // \r is the start of the newline phrase
                    GetNextChar();                // ignores \n
                    GetNextChar();                // positions on the first char in the next line
                    m_sRulesLines += "\r\n";      // preserve the newline
                }
            }
        } // RulesFileReader

        /// <summary>
        /// Attempts to open a file specified by the file path sFilePath. If it cannot, 
        ///     false is returned and the user is sent some hate mail. Otherwise, true 
        ///     is returned. 
        /// </summary>
        /// <param name="sFilePath"></param>
        /// <returns></returns>
        private bool OpenFile(string sFilePath)
        {
            try // try to open the file
            {
                m_fin = new FileStream(sFilePath, FileMode.Open); // if it works, great!
            }
            catch (Exception e) // otherwise, yell at the user some more
            {
                string strMsg = String.Format("File {0} failed to open. Make sure you have the correct file path and that the file is not already open. {1}",
                    sFilePath, e.Message);
                MessageBox.Show(strMsg, "Rules_Database - RulesFileReader - OpenFile", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }
            return true;
        } // OpenFile

        /// <summary>
        /// Reads the next char from the open file and stores it in the private 
        ///     data member m_CurChar.
        /// </summary>
        private void GetNextChar()
        {
            m_cCurChar = (char)m_fin.ReadByte();
            m_cCurChar = char.ToUpper(m_cCurChar);
        } // GetNextChar

        /// <summary>
        /// Accessor function. Returns the string of rules read from the file.
        /// </summary>
        /// <returns></returns>
        public string GetRules()
        {
            return m_sRulesLines;
        } // GetRules
    }
}
